package org.particles.domain.world;

import org.particles.domain.Particle;
import org.particles.domain.Vector;
import org.particles.domain.Vector2D;

/**
 * applies gravitation to worlds bounds. not synchronized.
 */
public class GravitationOobr implements OutOfWorldBoundResolver {
	public static final int SIDE_NORTH = 1;
	public static final int SIDE_EAST = 2;
	public static final int SIDE_SOUTH = 4;
	public static final int SIDE_WEST = 8;
	private final Vector2D forceVector = new Vector2D();
	private double accelerationRate = 0.1;
	private int side = SIDE_SOUTH;
	
	public GravitationOobr(final int side, final double accelerationRate) {
		super();
		this.accelerationRate = accelerationRate;
		this.side = side;
	}

	@Override
	public void resolve(World world, int particleIndex) {
		final Particle particle = world.getParticles().get(particleIndex);
		final Vector impulse = particle.getImpulse();
		if((side & SIDE_SOUTH) > 0) {
			forceVector.setCoordinate(0, accelerationRate);
			impulse.add(forceVector);
		}
		if((side & SIDE_NORTH) > 0) {
			forceVector.setCoordinate(0, -accelerationRate);
			impulse.add(forceVector);
		}
		if((side & SIDE_WEST) > 0) {
			forceVector.setCoordinate(-accelerationRate, 0);
			impulse.add(forceVector);
		}
		if((side & SIDE_EAST) > 0) {
			forceVector.setCoordinate(accelerationRate, 0);
			impulse.add(forceVector);
		}
	}

	public void setAccelerationRate(double accelerationRate) {
		this.accelerationRate = accelerationRate;
	}

	public double getAccelerationRate() {
		return accelerationRate;
	}

}
